/* Light Utilities */

// Light Info
static const uint LightType_DirectionalLight = 0x0000;
static const uint LightType_OmniLight = 0x0001;

// Light Info Structure
struct LightInfo
{
	float3	Position;
	float	Range;
	float3	Direction;
	float	Intensity;
	uint	LightType;
	float3	Padding;
};

// Calculate the Diffuse Term for a Directional Light
float CalculateDiffuseTerm_Directional(LightInfo light, float4 position, float3 normal)
{
	float diffuseTerm = 0.0f;

	diffuseTerm = saturate(dot(normal, -light.Direction));

	return diffuseTerm;
}
// Calculate the Diffuse Term for an Omni Light
float CalculateDiffuseTerm_Omni(LightInfo light, float4 position, float3 normal)
{
	float diffuseTerm = 0.0f;

	float dist = distance(light.Position, position.xyz);
	if (dist <= light.Range)
	{
		float3 lightNormal = normalize(light.Position - position.xyz);
			diffuseTerm = saturate(dot(normal, lightNormal));

		float distanceTerm = 1.0f - (dist / light.Range);
		diffuseTerm *= distanceTerm;
	}

	return diffuseTerm;
}

// Calculate the Diffuse Term for a Light
float CalculateDiffuseTerm(LightInfo light, float4 position, float3 normal)
{
	float diffuseTerm = 0.0f;

	if (light.LightType == LightType_DirectionalLight)
		diffuseTerm = CalculateDiffuseTerm_Directional(light, position, normal);
	if (light.LightType == LightType_OmniLight)
		diffuseTerm = CalculateDiffuseTerm_Omni(light, position, normal);

	return diffuseTerm;
}

// Calculate the Specular Term for a Directional Light
float CalculateSpecularTerm_Directional(LightInfo light, float4 position, float3 normal, float3 cameraPos, float power)
{
	float specularTerm = 0.0f;

	float3 lightDir = normalize(light.Direction);
	float3 viewDir = normalize(position.xyz - cameraPos);
	float3 r = normalize(2 * dot(lightDir, normal) * normal - lightDir);

	float dotProduct = dot(r, viewDir);
	specularTerm = max(pow(abs(dotProduct), power), 0.0f);

	return specularTerm;
}
// Calculate the Specular Term for an Omni Light
float CalculateSpecularTerm_Omni(LightInfo light, float4 position, float3 normal, float3 cameraPos, float power)
{
	float specularTerm = 0.0f;

	return specularTerm;
}

// Calculate the Specular Term for a Light
float CalculateSpecularTerm(LightInfo light, float4 position, float3 normal, float3 cameraPos, float power)
{
	float specularTerm = 0.0f;

	if (light.LightType == LightType_DirectionalLight)
		specularTerm = CalculateSpecularTerm_Directional(light, position, normal, cameraPos, power);
	if (light.LightType == LightType_OmniLight)
		specularTerm = CalculateSpecularTerm_Omni(light, position, normal, cameraPos, power);

	return specularTerm;
}

// Calculate the Reflection Vector
float3 CalculateReflectionVector(float3 eyePos, float4 position, float3 normal)
{
	float3 eyeDir = normalize(position.xyz - eyePos);
	//eyeDir = normalize(float3(-1.0f, -1.0f, 0.0f));
	float3 norm = normalize(normal);

	float3 reflectVector = reflect(eyeDir, norm);
	return reflectVector;
}